#ifndef MDTX_USE_RCPPARMADILLO
#define MDTX_USE_RCPPARMADILLO
#endif

#include <RcppArmadillo.h>
using namespace Rcpp;

#include "mdtx-online/indicator/indicator_type_s4_skewness.h"
using namespace mdtx::online;

#include "indi_common.h"

using rollskew_np_ = indi3<indicator::rollskew_np>;

//' Rolling skewness, nonparametric
//'
//' @param x Numeric vector x
//' @param period Period of rolling window
//' @return List of centre/mean, scale/sd and skewness of x
//' @export
// [[Rcpp::export(rng = false)]]
List rollskew_np(NumericVector x, int period)
{
    auto c = rollskew_np_::create_t(period);
    auto ans = rollskew_np_::run_t(c, x);
    ans.names() = CharacterVector::create("center", "scale", "skew");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP rollskew_np_new(int period)
{
    return rollskew_np_::create(period);
}

// [[Rcpp::export(rng = false)]]
List rollskew_np_run(SEXP ptr, NumericVector x)
{
    auto ans = rollskew_np_::run(ptr, x);
    ans.names() = CharacterVector::create("center", "scale", "skew");
    return ans;
}

using rollskew_npw_ = indi3<indicator::rollskew_npw>;

//' Rolling weighted skewness, nonparametric
//'
//' @param x Numeric vector x
//' @param w Numeric vector weight
//' @param period Period of rolling window
//' @return List of centre/mean, scale/sd and skewness of x
//' @export
// [[Rcpp::export(rng = false)]]
List rollskew_npw(NumericVector x, NumericVector w, int period)
{
    auto c = rollskew_npw_::create_t(period);
    auto ans = rollskew_npw_::run_t(c, x, w);
    ans.names() = CharacterVector::create("center", "scale", "skew");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP rollskew_npw_new(int period)
{
    return rollskew_npw_::create(period);
}

// [[Rcpp::export(rng = false)]]
List rollskew_npw_run(SEXP ptr, NumericVector x, NumericVector w)
{
    auto ans = rollskew_npw_::run(ptr, x, w);
    ans.names() = CharacterVector::create("center", "scale", "skew");
    return ans;
}

using rollskew_mc_ = indi3<indicator::rollskew_mc>;

//' Rolling skewness, medcouple
//'
//' @param x Numeric vector x
//' @param period Period of rolling window
//' @param u Upper quantile used to calculate iqr
//' @param eps1 floating point epsilon
//' @param eps2 min representable positive floating point
//' @return List of centre/median, scale/iqr and skewness of x
//' @export
// [[Rcpp::export(rng = false)]]
List rollskew_mc(NumericVector x, int period, double u = 0.75, double eps1 = 1.0e-14, double eps2 = 1.0e-16)
{
    auto c = rollskew_mc_::create_t(period, u, eps1, eps2);
    auto ans = rollskew_mc_::run_t(c, x);
    ans.names() = CharacterVector::create("center", "scale", "skew");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP rollskew_mc_new(int period, double u = 0.75, double eps1 = 1.0e-14, double eps2 = 1.0e-16)
{
    return rollskew_mc_::create(period, u, eps1, eps2);
}

// [[Rcpp::export(rng = false)]]
List rollskew_mc_run(SEXP ptr, NumericVector x)
{
    auto ans = rollskew_mc_::run(ptr, x);
    ans.names() = CharacterVector::create("center", "scale", "skew");
    return ans;
}

using rollskew_quantile_ = indi3<indicator::rollskew_quantile>;

//' Rolling skewness, quantile
//'
//' @param x Numeric vector x
//' @param period Period of rolling window
//' @param u Upper quantile
//' @return List of centre/median, scale/iqr and skewness of x
//' @export
// [[Rcpp::export(rng = false)]]
List rollskew_quantile(NumericVector x, int period, double u = 0.75)
{
    auto c = rollskew_quantile_::create_t(period, u);
    auto ans = rollskew_quantile_::run_t(c, x);
    ans.names() = CharacterVector::create("center", "scale", "skew");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP rollskew_quantile_new(int period, double u = 0.75)
{
    return rollskew_quantile_::create(period, u);
}

// [[Rcpp::export(rng = false)]]
List rollskew_quantile_run(SEXP ptr, NumericVector x)
{
    auto ans = rollskew_quantile_::run(ptr, x);
    ans.names() = CharacterVector::create("center", "scale", "skew");
    return ans;
}

using rollskew_G1_ = indi3<indicator::rollskew_G1>;

//' Rolling skewness, G1
//'
//' @param x Numeric vector x
//' @param period Period of rolling window
//' @return List of centre/mean, scale/sd and skewness of x
//' @export
// [[Rcpp::export(rng = false)]]
List rollskew_G1(NumericVector x, int period)
{
    auto c = rollskew_G1_::create_t(period);
    auto ans = rollskew_G1_::run_t(c, x);
    ans.names() = CharacterVector::create("center", "scale", "skew");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP rollskew_G1_new(int period)
{
    return rollskew_G1_::create(period);
}

// [[Rcpp::export(rng = false)]]
List rollskew_G1_run(SEXP ptr, NumericVector x)
{
    auto ans = rollskew_G1_::run(ptr, x);
    ans.names() = CharacterVector::create("center", "scale", "skew");
    return ans;
}
